package com.example.monit.service;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.BulkResponse;
import co.elastic.clients.elasticsearch.core.bulk.BulkOperation;
import co.elastic.clients.elasticsearch.sql.QueryResponse;
import co.elastic.clients.json.JsonData;
import com.example.monit.bean.ClickBehavior;
import com.example.monit.bean.ResponseRust;
import com.example.monit.dto.QueryClickDto;
import com.example.monit.enums.IndexName;
import com.example.monit.vo.ClickBehaviorVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.io.IOException;
import java.time.ZoneOffset;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ClickBehaviorServiceImpl implements ClickBehaviorService {

    @Autowired
    ElasticsearchClient client;
    @Override
    public ResponseRust upLoadClickBehavior(List<ClickBehavior> clickBehavior) throws IOException {
//        List<BulkOperation> operationList = clickBehavior.stream().map(e ->
//                        BulkOperation.of(builder ->
//                                builder.index(builder1 -> builder1.document(e).index(IndexName.ClickBehavior))))
//                .collect(Collectors.toList());
//        BulkResponse response = client.bulk(builder -> builder.operations(operationList));
//        if (response.errors()) {
//            log.error("上报数据异常错误");
//        }
        return ResponseRust.success_creat();
    }

    @Override
    public ResponseRust queryClickBehavior(ClickBehaviorVo clickbehaviorVo) throws IOException {
        String sql =" SELECT target,count(target),inner ,userID,pageUrl\n" +
                "            FROM \"click_behavior\" \n" +
                "            where appId=%s and mainType=%d and subType=%d and startTime between %d and %d\n" +
                "            group by target,inner, userID,pageUrl\n" +
                "            order by count(target) desc";

        sql = String.format(sql,
                clickbehaviorVo.getApp_id(),
                clickbehaviorVo.getMain_type(),
                clickbehaviorVo.getSub_type(),
                clickbehaviorVo.getStart_time().toInstant(ZoneOffset.of("+0")).toEpochMilli(),
                clickbehaviorVo.getEnd_time().toInstant(ZoneOffset.of("+0")).toEpochMilli() //todo 时区问题
        );

        String finalSql = sql;
        QueryResponse query = client.sql().query(e -> e.query(finalSql));
        List<List<JsonData>> list = query.rows();

        HashMap<String, QueryClickDto> map = new HashMap<>();
        for (List<JsonData> jsonData : list) {
            String target = jsonData.get(0).to(String.class);
            Integer count = jsonData.get(1).to(Integer.class);
            String inner = jsonData.get(2).to(String.class);
            String userID = jsonData.get(3).to(String.class);
            String pageUrl = jsonData.get(4).to(String.class);

            QueryClickDto build = QueryClickDto.builder()
                    .target(target)
                    .inner(inner)
                    .userCount(1)
                    .pageCount(1)
                    .count(count)
                    .userList(Arrays.asList(userID))
                    .pageList(Arrays.asList(pageUrl))
                    .build();

            String key = target+inner;
            QueryClickDto queryDto = map.get(key);
            if (ObjectUtils.isEmpty(queryDto)) {
                map.put(pageUrl, build);
            } else {
                if (!queryDto.getUserList().contains(userID)) {
                    queryDto.setUserCount(queryDto.getUserCount() + 1);
                    queryDto.getUserList().add(userID);
                }
                if (!queryDto.getPageList().contains(pageUrl)) {
                    queryDto.setPageCount(queryDto.getPageCount() + 1);
                    queryDto.getPageList().add(pageUrl);
                }
                queryDto.setCount(queryDto.getCount() + build.getCount());
            }
        }

        Collection<QueryClickDto> values = map.values();
        if (!ObjectUtils.isEmpty(clickbehaviorVo.getSize())) {
            values = values.stream().limit(clickbehaviorVo.getSize()).collect(Collectors.toList());
        }
        return ResponseRust.success(values);
    }

}
